

import EventEmitter from "events";
import { roundTimeToInterval, PERIOD_INTERVAL_MAP } from "../utils/date";
export type Period = '5m' | '15m' | '4h' | '1d';

export class PeriodProcess<T extends { timestamp: number }> {
    private eventEmitter = new EventEmitter();

    private periods: Period[];
    private PRE_PERIOD_INTERVAL_MAP: Record<string, {
      prePeriodTime: number | undefined
      count: number;
    }>;
    private dataMap: Record<Period, Record<number, T>>;
    private asyncTaskCount: number;
    constructor(periods: Period[], asyncTaskCount = 2) {
      this.asyncTaskCount = asyncTaskCount;
      this.periods = periods;
      this.PRE_PERIOD_INTERVAL_MAP = {};      
      this.dataMap = {
        '5m': {},
        '15m': {},
        '4h': {},
        '1d': {},
      };
    }
    onPeriod(callback: (period: Period, data: T) => void) {
      this.eventEmitter.on('complete', callback);
    }
    onUpdate(callback: (period: Period, data: T) => void) {
      this.eventEmitter.on('update', callback);
    }
    process(timestamp: number, hander: (oldData: T) => void) {
  
      this.periods.forEach((period) => {
        let isUpdate = true;
        const periodTime = roundTimeToInterval(period, timestamp);
    
        // 第一次
        if (this.PRE_PERIOD_INTERVAL_MAP[period] === undefined) { 
          this.dataMap[period][periodTime] = {
            timestamp: periodTime,
          } as T;
          this.PRE_PERIOD_INTERVAL_MAP[period] = {
            prePeriodTime: periodTime,
            count: 0,
          };
          isUpdate = false;
        } else if (this.dataMap[period][periodTime] == undefined) {
          //新周期数据
          this.dataMap[period][periodTime] = {
            timestamp: periodTime,
          } as T;
          isUpdate = false;
        }
     
        // 下一批周期数据
        if (this.PRE_PERIOD_INTERVAL_MAP[period] !== undefined && periodTime > this.PRE_PERIOD_INTERVAL_MAP[period].prePeriodTime) {
          // console.log('新的周期数据', period, periodTime, this.PRE_PERIOD_INTERVAL_MAP, this.PRE_PERIOD_INTERVAL_MAP[period].count, this.asyncTaskCount - 1)
          
          if (this.PRE_PERIOD_INTERVAL_MAP[period].count > this.asyncTaskCount - 1) {
            isUpdate = false;
            const preData = this.dataMap[period][this.PRE_PERIOD_INTERVAL_MAP[period].prePeriodTime]
            // 通知
            this.eventEmitter.emit('complete', period, preData);
            // 记录新周期时间
            this.PRE_PERIOD_INTERVAL_MAP[period].prePeriodTime = periodTime;
            const disTime = periodTime -  2 * PERIOD_INTERVAL_MAP[period];
            // 删除上上个周期的数据
            if (this.dataMap[period][disTime]) {
              delete this.dataMap[period][disTime];
            } else {
              const keys = Object.keys(this.dataMap[period]);
              if (keys.length > 2) {
                delete this.dataMap[period][keys[0]];
              }
            }
          } else {
            this.PRE_PERIOD_INTERVAL_MAP[period].count++;
          }
        }
      
        // 合并数据处理
        hander(this.dataMap[period][periodTime]);

        if (isUpdate) {
          this.eventEmitter.emit('update', period, this.dataMap[period][periodTime]);
        }
      });
    }
    end() {
      this.periods.forEach((period) => {
        const preData = this.dataMap[period][this.PRE_PERIOD_INTERVAL_MAP[period].prePeriodTime];
        if (preData) {
          this.eventEmitter.emit('complete', period, preData);
          delete this.dataMap[period][this.PRE_PERIOD_INTERVAL_MAP[period].prePeriodTime];
        }
      });
    }
}
